package com.wmyg.tracker.listenner;

import com.alibaba.fastjson.JSON;
import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Envelope;
import com.wmyg.tracker.bean.QRInfo;
import com.wmyg.tracker.dao.FabricDao;
import com.wmyg.tracker.message.TrackApplyMessage;
import com.wmyg.tracker.message.TrackMessage;
import com.wmyg.tracker.sdk.FabricException;
import lombok.extern.slf4j.Slf4j;
import org.hyperledger.fabric.sdk.exception.ProposalException;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageBuilder;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.support.MessagePropertiesConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.FileNotFoundException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException;

@Slf4j
@Component
public class TrackListenner {

    @Autowired
    MessagePropertiesConverter messagePropertiesConverter;

    @Autowired
    RabbitTemplate rabbitTemplate;

    @Autowired
    FabricDao fabricDao;

    @RabbitListener(queues = "trackMessageQueue")
    public void tracker(Message message, Channel channel) {
        log.info("Get message from antifake");
        try {
            MessageProperties messageProperties = message.getMessageProperties();
            AMQP.BasicProperties rabbitMQProperties =
                    messagePropertiesConverter.fromMessageProperties(messageProperties, "UTF-8");
            String messageContent = null;
            messageContent = new String(message.getBody(),"UTF-8");
            String consumerTag = messageProperties.getConsumerTag();
            log.info(consumerTag+ " get The message content is:" + messageContent);

            TrackMessage trackMessage = JSON.parseObject(messageContent, TrackMessage.class);
            TrackApplyMessage trackApplyMessage = new TrackApplyMessage();
            if (System.currentTimeMillis() - messageProperties.getTimestamp().getTime() < 20000) {
                try {
                    QRInfo qrInfo = fabricDao.query(trackMessage.getQR(), trackMessage.getQueryInfo());
                    trackApplyMessage.setQrInfo(qrInfo);
                    trackApplyMessage.setExceptionCode(0);
                    trackApplyMessage.setExceptionMessage("no exception");
                } catch (FileNotFoundException e) {
                    trackApplyMessage.setExceptionCode(1);
                    trackApplyMessage.setExceptionMessage("FileNotFoundException");
                    e.printStackTrace();
                } catch (ProposalException e) {
                    trackApplyMessage.setExceptionCode(2);
                    trackApplyMessage.setExceptionMessage(e.getMessage());
                    e.printStackTrace();
                } catch (TimeoutException e) {
                    trackApplyMessage.setExceptionCode(3);
                    trackApplyMessage.setExceptionMessage("TimeoutException");
                    e.printStackTrace();
                } catch (FabricException e) {
                    trackApplyMessage.setExceptionCode(4);
                    trackApplyMessage.setExceptionMessage(e.getMessage());
                    e.printStackTrace();
                } catch (ExecutionException e) {
                    trackApplyMessage.setExceptionCode(5);
                    trackApplyMessage.setExceptionMessage("ExecutionException");
                    e.printStackTrace();
                } catch (Throwable e) {
                    trackApplyMessage.setExceptionCode(6);
                    trackApplyMessage.setExceptionMessage(e.getMessage());
                    e.printStackTrace();
                }
            } else {
                log.info("The message {} is timeout", messageContent);
                trackApplyMessage.setExceptionCode(3);
                trackApplyMessage.setExceptionMessage("TimeoutException");
            }

            String replyMessageContent = JSON.toJSONString(trackApplyMessage);

            String cId = rabbitMQProperties.getCorrelationId();
            AMQP.BasicProperties replyRabbitMQProps =
                    new AMQP.BasicProperties("text/plain",
                            "UTF-8",
                            null,
                            2,
                            0, cId, null, null,
                            null, null, null, null,
                            consumerTag, null);
            Envelope replyEnvelope =
                    new Envelope(messageProperties.getDeliveryTag(), true,
                            "trackReplyMessageExchange", "trackReplyMessage");

            MessageProperties replyMessageProperties =
                    messagePropertiesConverter.toMessageProperties(replyRabbitMQProps,
                            replyEnvelope,"UTF-8");

            Message replyMessage = MessageBuilder.withBody(replyMessageContent.getBytes("UTF-8"))
                    .andProperties(replyMessageProperties)
                    .build();


            rabbitTemplate.send("trackReplyMessageExchange","trackReplyMessage", replyMessage);
            log.info("Handled the message and send it back");
            channel.basicAck(messageProperties.getDeliveryTag(), false);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
